﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Generic;

namespace innovations.ml.core
{
    public class Gradient
    {
        public static void RunGradientDescent(DataManager dm, int iterations, double alpha, bool saveJ_History)
        {
            if(saveJ_History)
                dm.J_History = new DenseVector(iterations, 0.0);
            for (int i = 0; i < iterations; i++)
            {
                Gradient.Run(dm, alpha);
                Cost.ComputeLinearRegressionCost(dm);
                if (saveJ_History)
                    dm.J_History[i] = dm.J;
            }
        }

        private static void Run(DataManager dm, double alpha)
        {
            double m = dm.Y.Count;
            Vector<double> temp = new DenseVector(dm.X.ColumnCount);
            for (int j = 0; j < dm.X.ColumnCount; j++)
            {
                Vector<double> vector = ((dm.X).Multiply(dm.Theta)).Subtract(dm.Y);
                Vector<double> xVector = dm.X.Column(j);
                temp[j] = dm.Theta[j] - (alpha * (1 / m) * (vector.DotProduct(xVector)));
            }
            dm.Theta = temp;
        }
    }
}
